import {dirname, join} from 'node:path'
import {fileURLToPath} from 'node:url'

import fs from 'fs-jetpack'
// @eslint-disable-next-line node/no-unpublished-import
import {compile} from 'json-schema-to-typescript'
import _ from 'lodash'

/**
 * WordPress theme.json contains keys which are not parseable by TypeScript
 *
 * This function replaces the keys with a regex that will match the key
 * and allow TypeScript to parse the schema.
 *
 * @param {Record<string, any>} records
 */
const fixRecords = records => {
  if (!records) return {}

  return Object.entries(records).reduce((acc, [k, v]) => {
    k = k.replaceAll(
      `[a-z][a-z0-9-]*/[a-z][a-z0-9-]`,
      `[a-z][a-z0-9-]*\\/[a-z][a-z0-9-]`,
    )
    v = _.isObject(v) && !_.isArray(v) ? fixRecords(v) : v
    return {...acc, [k]: v}
  }, {})
}

let data

try {
  const response = await fetch(
    `https://raw.githubusercontent.com/WordPress/gutenberg/trunk/schemas/json/theme.json`,
  )
  if (!response.ok) {
    throw new Error(`Network response was not OK`)
  }

  /** Fix keys when setting response */
  data = fixRecords(await response.json())
} catch (err) {
  throw err
}

try {
  data = await compile(data, `WordPressThemeSchema`, {
    bannerComment: `/**
 * This file was automatically generated by bud.js using json-schema-to-typescript.
 * Do not edit this file directly.
 *
 * To update typings run:
 * \`yarn workspace @roots/wordpress-theme-json-webpack-plugin exec node ./scripts/build-types.js\`
 */

// @ts-nocheck
// eslint-disable
`,
  })
} catch (err) {
  throw err
}

try {
  data = data.replaceAll(
    /JSONSchemaForWordPressBlockThemeGlobalSettingsAndStyles/g,
    `SettingsAndStyles`,
  )
} catch (err) {
  throw err
}

try {
  await fs.writeAsync(
    join(dirname(fileURLToPath(import.meta.url)), `..`, `src`, `theme.ts`),
    data,
  )
} catch (err) {
  throw err
}

/** Top-level await only available in modules */
export {}
